/*
 * Camera.hpp
 *
 *  Created on: 25.05.2014
 *      Author: philipp
 */

#ifndef CAMERA_HPP_
#define CAMERA_HPP_

#include <opencv2/opencv.hpp>
#include <raspicam/raspicam_cv.h>
#include "wiringPi.h"
#include <exception>

/*
 * Exception thrown if the camera could not be initialized.
 */
class CameraInitException: public std::exception {
public:
	const char *what() const noexcept {
		return "Error initializing camera. Make sure it is plugged in.";
	}
};

/*
 * Exception thrown if the camera could not shoot an image
 */
class CameraPictureError: public std::exception {
public:
	const char *what() const noexcept {
		return "Error taking picture.";
	}
};

/*
 * Wrapper class around the default raspicam class for easier usage.
 */
class Camera {
private:
	//internal raspicam camera object
	raspicam::RaspiCam_Cv cameraObject;

	//private for singleton pattern.
	Camera();
	Camera(const Camera &);
	Camera(Camera &&);
	Camera &operator=(const Camera &);
	Camera &operator=(Camera &&);
	~Camera();
public:
	/*
	 * Returs a reference to the one and only camera object. will initialize the camera if it does not exist.
	 * WARNING: initializing the camera can take a couple seconds, this is mandatory to avoid hardware errors.
	 */
	static Camera &getInstance();

	/*
	 * Takes a black and white image with a 640*480 resolution and returns it as cv::mat.
	 */
	cv::Mat takeImage();

	/*
	 * Takes an image and formats it to 100x100 resolution. This is the image size used for the eigenface algorythm.
	 */
	cv::Mat takeFormattedImage();

	/**Sets a property in the VideoCapture.
	 *
	 * Implemented properties:
	 * CV_CAP_PROP_FRAME_WIDTH,CV_CAP_PROP_FRAME_HEIGHT,
	 * CV_CAP_PROP_FORMAT: CV_8UC1 or CV_8UC3
	 * CV_CAP_PROP_BRIGHTNESS: [0,100]
	 * CV_CAP_PROP_CONTRAST: [0,100]
	 * CV_CAP_PROP_SATURATION: [0,100]
	 * CV_CAP_PROP_GAIN: (iso): [0,100]
	 * CV_CAP_PROP_EXPOSURE: -1 auto. [1,100] shutter speed from 0 to 33ms
	 *
	 */
	bool setProperty(int propId, double value);
};

#endif /* CAMERA_HPP_ */
